package cn.wolfcode.luowowo.service.impl;

import cn.wolfcode.luowowo.cache.key.RedisKey;
import cn.wolfcode.luowowo.cache.service.IViewpointStatsCacheService;
import cn.wolfcode.luowowo.cache.vo.ViewpointStats;
import cn.wolfcode.luowowo.common.util.AjaxResult;
import cn.wolfcode.luowowo.common.util.DateUtil;
import com.alibaba.fastjson.JSON;
import org.apache.dubbo.config.annotation.Service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.ValueOperations;

import java.util.*;
import java.util.concurrent.TimeUnit;

@Service
public class ViewpointStatsCacheServiceImpl implements IViewpointStatsCacheService {

    @Autowired
    private StringRedisTemplate template;

    @Override
    public void setViewpointStats(ViewpointStats vo) {
        String cacheKey = RedisKey.VIEWPOINT_STATS.getCacheKey(vo.getViewpointId());
        template.opsForValue().set(cacheKey, JSON.toJSONString(vo));
    }

    @Override
    public boolean hasStatsKey(Long viewpointId) {
        String cacheKey = RedisKey.VIEWPOINT_STATS.getCacheKey(viewpointId);
        return template.hasKey(cacheKey);
    }

    @Override
    public ViewpointStats getViewpointStats(Long viewpointId) {
        String cacheKey = RedisKey.VIEWPOINT_STATS.getCacheKey(viewpointId);
        String json = template.opsForValue().get(cacheKey);
        return JSON.parseObject(json, ViewpointStats.class);
    }

    @Override
    public void incrNum(Long viewpointId, int num, int type) {
        //根据id查询文章
        ViewpointStats vo = getViewpointStats(viewpointId);
        //很久类型偏移值
        switch (type) {
            case VIEWPOINT_STATS_CAMENUM:
                vo.setCamenum(vo.getCamenum() + num);
                break;

            case VIEWPOINT_STATS_REPLYNUM:
                vo.setReplynum(vo.getReplynum() + num);
                break;
            case VIEWPOINT_STATS_FAVORNUM:
                vo.setFavornum(vo.getFavornum() + num);
                break;
            case VIEWPOINT_STATS_THUMBSUPNUM:
                vo.setThumbsupnum(vo.getThumbsupnum() + num);
                break;
        }
        setViewpointStats(vo);
    }

    @Override
    public boolean favor(Long viewpointId, Long userId) {
        boolean flag = true;
        ValueOperations<String, String> op = template.opsForValue();
        //获取文章的所有收藏者在redis中的key
        String cacheKey = RedisKey.VIEWPOINT_STATS_FAVOR.getCacheKey(viewpointId);
        //user,所有收藏者的id
        List<Long> users = new ArrayList<>();
        //num:偏移值
        int num = 0;
        //判断是否有被收藏过
        Boolean hasKey = template.hasKey(cacheKey);
        if (hasKey) {//有被收藏
            //查询redis中的收藏者
            String vo = op.get(cacheKey);
            //将字符串数据解析成Long类型的数据
            users = JSON.parseArray(vo, Long.class);
            //判断users中是否已有当前登录用户
            if (users.contains(userId)) {
                //取消收藏
                users.remove(userId);
                num = -1;
                flag = false;
            } else {
                //收藏
                users.add(userId);
                num = 1;
            }
        } else {//文章第一次被收藏
            //将当前登录用户id加入list集合
            users.add(userId);
            num = 1;
        }
        //将users存进redis
        op.set(cacheKey, JSON.toJSONString(users));
        //更新收藏数据
        incrNum(viewpointId, num, VIEWPOINT_STATS_FAVORNUM);
        return flag;
    }

    //是否有收藏
    public boolean isFavor(Long viewpointId, Long userId) {
        String cacheKey = RedisKey.VIEWPOINT_STATS_FAVOR.getCacheKey(viewpointId);
        String vo = template.opsForValue().get(cacheKey);
        if (vo != null) {
            List<Long> users = JSON.parseArray(vo, Long.class);
            return users.contains(userId);
        }
        return false;
    }

    @Override
    public boolean viewpointThumbup(Long viewpointId, Long userId) {
        boolean flag = false;
        //判断当前攻略在缓存在是否有key
        String key = viewpointId.toString() + ":" + userId.toString();
        String cacheKey = RedisKey.VIEWPOINT_STATS_THUMBUP.getCacheKey(key);
        if (!template.hasKey(cacheKey)) {//没有顶过
            Date now = new Date();
            Date endDate = DateUtil.getEndDate(now);
            //往redis中存入key
            template.opsForValue().set(cacheKey, "", DateUtil.getDateBetween(now, endDate), TimeUnit.MILLISECONDS);
            //文章收藏数加1
            incrNum(viewpointId, 1, IViewpointStatsCacheService.VIEWPOINT_STATS_THUMBSUPNUM);
            flag = true;
        }
        return flag;
    }

    @Override
    public List<ViewpointStats> listAllStrateg() {
        ValueOperations<String, String> op = template.opsForValue();
        List<ViewpointStats> vos = new ArrayList<>();
        //根据前缀获取key的集合
        String cacheKey = RedisKey.VIEWPOINT_STATS.getCacheKey("*");
        Set<String> keys = template.keys(cacheKey);
        //遍历,将文章数据存进vos
        for (String key : keys) {
            //获取文章数据
            String vo = op.get(key);
            vos.add(JSON.parseObject(vo, ViewpointStats.class));
        }
        return vos;
    }

    @Override
    public void addScore(RedisKey key, int num, Long detailId) {
        String value = RedisKey.VIEWPOINT_STATS.getCacheKey(detailId);
        template.opsForZSet().incrementScore(key.getPrefix(), value, num);
    }

    @Override
    public boolean exist(RedisKey key, Long detailId) {
        String value = RedisKey.VIEWPOINT_STATS.getCacheKey(detailId);
        Long rank = template.opsForZSet().rank(key.getPrefix(), value);
        return rank == null;
    }

    @Override
    public List<ViewpointStats> listCommends(RedisKey key) {
        List<ViewpointStats> list = new ArrayList<>();
        ValueOperations<String, String> op = template.opsForValue();
        Set<String> set = template.opsForZSet().reverseRange(key.getPrefix(), 0, 9);
        for (String s : set) {
            String vo = op.get(s);
            list.add(JSON.parseObject(vo, ViewpointStats.class));
        }
        return list;
    }

    //设置去过状态
    public boolean setCame(Long viewId, Long userId) {
        boolean flag = true;
        ValueOperations<String, String> op = template.opsForValue();
        //获取文章的所有收藏者在redis中的key
        String cacheKey = RedisKey.VIEWPOINT_STATS_CAME.getCacheKey(viewId);
        //user,所有去过人的id
        List<Long> users = new ArrayList<>();
        //num:偏移值
        int num = 1;
        //判断是否有记录有人去过
        Boolean hasKey = template.hasKey(cacheKey);
        if (!hasKey) {//没有有记录有人去过
            //添加去过记录
            users.add(userId);
        } else {
            //查询redis中的收藏者
            String vo = op.get(cacheKey);
            //将字符串数据解析成Long类型的数据
            users = JSON.parseArray(vo, Long.class);
            //判断users中是否已有当前登录用户
            if (!users.contains(userId)) {
                //取消收藏
                users.add(userId);
            } else {
                flag = false;
                return flag;
            }
        }
        //将users存进redis
        op.set(cacheKey, JSON.toJSONString(users));
        //更新收藏数据
        incrNum(viewId, num, VIEWPOINT_STATS_CAMENUM);
        return flag;
    }

    //记录是否来过
    public boolean isCame(Long pointId, Long userId) {
        String cacheKey = RedisKey.VIEWPOINT_STATS_CAME.getCacheKey(pointId);
        String vo = template.opsForValue().get(cacheKey);
        if (vo != null) {
            List<Long> users = JSON.parseArray(vo, Long.class);
            return users.contains(userId);
        }
        return false;
    }

    //记录是否点过赞
    public List<Long> isThumbup(Long viewpointId, Long userId) {
        String cacheKey = RedisKey.VIEWPOINT_STATS_THUMBUP.getCacheKey(viewpointId, "*");
        //前缀：景点id：景点评论id
        Set<String> keys = template.keys(cacheKey);
        List<Long> commentIds = new ArrayList<>();
        if (keys != null && keys.size() > 0) {
            for (String key : keys) {
                String usersStr = template.opsForValue().get(key);
                List<Long> users = JSON.parseArray(usersStr, Long.class);
               if(users !=null && users.size()>0 && users.contains(userId)){
                   String commentId = key.substring(key.length() - 1);
                   commentIds.add(Long.valueOf(commentId));
               }
            }
            return commentIds;
        }
        return commentIds;
    }

    // 对景点的点评点赞
    public AjaxResult thumbup(Long viewpointId, Long viewCommentId, Long userId) {
        AjaxResult ajaxResult = new AjaxResult();
        boolean flag = true;
        ValueOperations<String, String> op = template.opsForValue();
        //获取文章的所有收藏者在redis中的key  viewpoint_stats_thumbup:viewpointId:viewCommentId
        String cacheKey = RedisKey.VIEWPOINT_STATS_THUMBUP.getCacheKey(viewpointId, viewCommentId);
        //user,所有去过人的id
        List<Long> users = new ArrayList<>();
        //num:偏移值
        int num = 1;
        //判断是否有记录有人去过
        Boolean hasKey = template.hasKey(cacheKey);
        if (!hasKey) {//没有有记录有人去过
            //添加去过记录
            users.add(userId);
        } else {
            //查询redis中的点赞记录者
            String vo = op.get(cacheKey);
            //将字符串数据解析成Long类型的数据
            users = JSON.parseArray(vo, Long.class);
            //判断users中是否已有当前登录用户
            if (!users.contains(userId)) {
                //没有就添加
                users.add(userId);
            } else {
                flag = false;
                ajaxResult.setSuccess(flag);
                return ajaxResult;
            }
        }
        //将users存进redis
        op.set(cacheKey, JSON.toJSONString(users));
        int thumbupNum = users.size();
        ajaxResult.setCode(thumbupNum);
        ajaxResult.addData(viewCommentId);
        ajaxResult.setSuccess(flag);
        return ajaxResult;
    }


}
